1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.codehaus.groovy.control;
20
21 import org.codehaus.groovy.control.customizers.CompilationCustomizer;
22 import org.codehaus.groovy.control.io.NullWriter;
23 import org.codehaus.groovy.control.messages.WarningMessage;
24
25 import java.io.File;
26 import java.io.PrintWriter;
27 import java.util.*;
28
29
30
31
32
33
34
35
36
37
38 public class CompilerConfiguration {
39
40 private static final String JDK5_CLASSNAME_CHECK = "java.lang.annotation.Annotation";
41
42
43 public static final String JDK4 = "1.4";
44
45 public static final String JDK5 = "1.5";
46
47 public static final String JDK6 = "1.6";
48
49 public static final String JDK7 = "1.7";
50
51 public static final String JDK8 = "1.8";
52
53
54 public static final String POST_JDK5 = JDK5;
55
56
57 public static final String PRE_JDK5 = JDK4;
58
59 private static final String[] ALLOWED_JDKS = { JDK4, JDK5, JDK6, JDK7, JDK8 };
60
61
62 public static final String currentJVMVersion = getVMVersion();
63
64
65
66
67
68
69
70
71
72 public static final CompilerConfiguration DEFAULT = new CompilerConfiguration();
73
74
75
76
77 private int warningLevel;
78
79
80
81
82
83 private String sourceEncoding;
84
85
86
87
88 private PrintWriter output;
89
90
91
92
93 private File targetDirectory;
94
95
96
97
98 private LinkedList<String> classpath;
99
100
101
102
103 private boolean verbose;
104
105
106
107
108 private boolean debug;
109
110
111
112
113 private int tolerance;
114
115
116
117
118 private String scriptBaseClass;
119
120 private ParserPluginFactory pluginFactory;
121
122
123
124
125 private String defaultScriptExtension;
126
127
128
129
130 private Set<String> scriptExtensions = new LinkedHashSet<String>();
131
132
133
134
135 private boolean recompileGroovySource;
136
137
138
139
140 private int minimumRecompilationInterval;
141
142
143
144
145 private String targetBytecode;
146
147
148
149
150 private Map<String, Object> jointCompilationOptions;
151
152
153
154
155 private Map<String, Boolean> optimizationOptions;
156
157 private List<CompilationCustomizer> compilationCustomizers = new LinkedList<CompilationCustomizer>();
158
159
160
161
162
163
164 private Set<String> disabledGlobalASTTransformations;
165
166 private BytecodeProcessor bytecodePostprocessor;
167
168
169
170
171 public CompilerConfiguration() {
172
173
174
175 setWarningLevel(WarningMessage.LIKELY_ERRORS);
176 setOutput(null);
177 setTargetDirectory((File) null);
178 setClasspath("");
179 setVerbose(false);
180 setDebug(false);
181 setTolerance(10);
182 setScriptBaseClass(null);
183 setRecompileGroovySource(false);
184 setMinimumRecompilationInterval(100);
185
186 String targetByteCode = null;
187 try {
188 targetByteCode = System.getProperty("groovy.target.bytecode", targetByteCode);
189 } catch (Exception e) {
190
191 }
192 if(targetByteCode != null) {
193 setTargetBytecode(targetByteCode);
194 } else {
195 setTargetBytecode(getVMVersion());
196 }
197 String tmpDefaultScriptExtension = null;
198 try {
199 tmpDefaultScriptExtension = System.getProperty("groovy.default.scriptExtension");
200 } catch (Exception e) {
201
202 }
203 if(tmpDefaultScriptExtension != null) {
204 setDefaultScriptExtension(tmpDefaultScriptExtension);
205 } else {
206 setDefaultScriptExtension(".groovy");
207 }
208
209
210
211 String encoding = null;
212 try {
213 encoding = System.getProperty("file.encoding", "US-ASCII");
214 } catch (Exception e) {
215
216 }
217 try {
218 encoding = System.getProperty("groovy.source.encoding", encoding);
219 } catch (Exception e) {
220
221 }
222 setSourceEncoding(encoding);
223
224 try {
225 setOutput(new PrintWriter(System.err));
226 } catch (Exception e) {
227
228 }
229
230 try {
231 String target = System.getProperty("groovy.target.directory");
232 if (target != null) {
233 setTargetDirectory(target);
234 }
235 } catch (Exception e) {
236
237 }
238
239 boolean indy = false;
240 try {
241 indy = Boolean.getBoolean("groovy.target.indy");
242 } catch (Exception e) {
243
244 }
245 if (DEFAULT!=null && Boolean.TRUE.equals(DEFAULT.getOptimizationOptions().get("indy"))) {
246 indy = true;
247 }
248 Map options = new HashMap<String,Boolean>(3);
249 if (indy) {
250 options.put("indy", Boolean.TRUE);
251 }
252 setOptimizationOptions(options);
253 }
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271 public CompilerConfiguration(CompilerConfiguration configuration) {
272 setWarningLevel(configuration.getWarningLevel());
273 setOutput(configuration.getOutput());
274 setTargetDirectory(configuration.getTargetDirectory());
275 setClasspathList(new LinkedList<String>(configuration.getClasspath()));
276 setVerbose(configuration.getVerbose());
277 setDebug(configuration.getDebug());
278 setTolerance(configuration.getTolerance());
279 setScriptBaseClass(configuration.getScriptBaseClass());
280 setRecompileGroovySource(configuration.getRecompileGroovySource());
281 setMinimumRecompilationInterval(configuration.getMinimumRecompilationInterval());
282 setTargetBytecode(configuration.getTargetBytecode());
283 setDefaultScriptExtension(configuration.getDefaultScriptExtension());
284 setSourceEncoding(configuration.getSourceEncoding());
285 setOutput(configuration.getOutput());
286 setTargetDirectory(configuration.getTargetDirectory());
287 Map<String, Object> jointCompilationOptions = configuration.getJointCompilationOptions();
288 if (jointCompilationOptions != null) {
289 jointCompilationOptions = new HashMap<String, Object>(jointCompilationOptions);
290 }
291 setJointCompilationOptions(jointCompilationOptions);
292 setPluginFactory(configuration.getPluginFactory());
293 setScriptExtensions(configuration.getScriptExtensions());
294 setOptimizationOptions(new HashMap<String, Boolean>(configuration.getOptimizationOptions()));
295 }
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351 public CompilerConfiguration(Properties configuration) throws ConfigurationException {
352 this();
353 configure(configuration);
354 }
355
356
357
358
359
360
361
362 public static boolean isPostJDK5(String bytecodeVersion) {
363 return JDK5.equals(bytecodeVersion)
364 || JDK6.equals(bytecodeVersion)
365 || JDK7.equals(bytecodeVersion)
366 || JDK8.equals(bytecodeVersion);
367 }
368
369
370
371
372
373
374
375 public static boolean isPostJDK7(String bytecodeVersion) {
376 return JDK7.equals(bytecodeVersion)
377 || JDK8.equals(bytecodeVersion);
378 }
379
380
381
382
383
384
385 public void configure(Properties configuration) throws ConfigurationException {
386 String text = null;
387 int numeric = 0;
388
389
390
391
392 numeric = getWarningLevel();
393 try {
394 text = configuration.getProperty("groovy.warnings", "likely errors");
395 numeric = Integer.parseInt(text);
396 } catch (NumberFormatException e) {
397 text = text.toLowerCase();
398 if (text.equals("none")) {
399 numeric = WarningMessage.NONE;
400 }
401 else if (text.startsWith("likely")) {
402 numeric = WarningMessage.LIKELY_ERRORS;
403 }
404 else if (text.startsWith("possible")) {
405 numeric = WarningMessage.POSSIBLE_ERRORS;
406 }
407 else if (text.startsWith("paranoia")) {
408 numeric = WarningMessage.PARANOIA;
409 }
410 else {
411 throw new ConfigurationException("unrecognized groovy.warnings: " + text);
412 }
413 }
414 setWarningLevel(numeric);
415
416
417
418
419 text = configuration.getProperty("groovy.source.encoding");
420 if (text == null) {
421 text = configuration.getProperty("file.encoding", "US-ASCII");
422 }
423 setSourceEncoding(text);
424
425
426
427
428 text = configuration.getProperty("groovy.target.directory");
429 if (text != null) setTargetDirectory(text);
430
431 text = configuration.getProperty("groovy.target.bytecode");
432 if (text != null) setTargetBytecode(text);
433
434
435
436
437 text = configuration.getProperty("groovy.classpath");
438 if (text != null) setClasspath(text);
439
440
441
442
443 text = configuration.getProperty("groovy.output.verbose");
444 if (text != null && text.equalsIgnoreCase("true")) setVerbose(true);
445
446
447
448
449 text = configuration.getProperty("groovy.output.debug");
450 if (text != null && text.equalsIgnoreCase("true")) setDebug(true);
451
452
453
454
455 numeric = 10;
456 try {
457 text = configuration.getProperty("groovy.errors.tolerance", "10");
458 numeric = Integer.parseInt(text);
459 } catch (NumberFormatException e) {
460 throw new ConfigurationException(e);
461 }
462 setTolerance(numeric);
463
464
465
466
467 text = configuration.getProperty("groovy.script.base");
468 if (text!=null) setScriptBaseClass(text);
469
470
471
472
473 text = configuration.getProperty("groovy.recompile");
474 if (text != null) {
475 setRecompileGroovySource(text.equalsIgnoreCase("true"));
476 }
477
478 numeric = 100;
479 try {
480 text = configuration.getProperty("groovy.recompile.minimumIntervall");
481 if (text==null) text = configuration.getProperty("groovy.recompile.minimumInterval");
482 if (text!=null) {
483 numeric = Integer.parseInt(text);
484 } else {
485 numeric = 100;
486 }
487 } catch (NumberFormatException e) {
488 throw new ConfigurationException(e);
489 }
490 setMinimumRecompilationInterval(numeric);
491
492
493 text = configuration.getProperty("groovy.disabled.global.ast.transformations");
494 if (text!=null) {
495 String[] classNames = text.split(",\\s*}");
496 Set<String> blacklist = new HashSet<String>(Arrays.asList(classNames));
497 setDisabledGlobalASTTransformations(blacklist);
498 }
499 }
500
501
502
503
504
505 public int getWarningLevel() {
506 return this.warningLevel;
507 }
508
509
510
511
512 public void setWarningLevel(int level) {
513 if (level < WarningMessage.NONE || level > WarningMessage.PARANOIA) {
514 this.warningLevel = WarningMessage.LIKELY_ERRORS;
515 }
516 else {
517 this.warningLevel = level;
518 }
519 }
520
521
522
523
524 public String getSourceEncoding() {
525 return this.sourceEncoding;
526 }
527
528
529
530
531 public void setSourceEncoding(String encoding) {
532 if (encoding == null) encoding = "US-ASCII";
533 this.sourceEncoding = encoding;
534 }
535
536
537
538
539 public PrintWriter getOutput() {
540 return this.output;
541 }
542
543
544
545
546 public void setOutput(PrintWriter output) {
547 if (output == null) {
548 this.output = new PrintWriter(NullWriter.DEFAULT);
549 }
550 else {
551 this.output = output;
552 }
553 }
554
555
556
557
558 public File getTargetDirectory() {
559 return this.targetDirectory;
560 }
561
562
563
564
565 public void setTargetDirectory(String directory) {
566 if (directory != null && directory.length() > 0) {
567 this.targetDirectory = new File(directory);
568 } else {
569 this.targetDirectory = null;
570 }
571 }
572
573
574
575
576 public void setTargetDirectory(File directory) {
577 this.targetDirectory = directory;
578 }
579
580
581
582
583 public List<String> getClasspath() {
584 return this.classpath;
585 }
586
587
588
589
590 public void setClasspath(String classpath) {
591 this.classpath = new LinkedList<String>();
592 StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator);
593 while (tokenizer.hasMoreTokens()) {
594 this.classpath.add(tokenizer.nextToken());
595 }
596 }
597
598
599
600
601
602 public void setClasspathList(List<String> parts) {
603 this.classpath = new LinkedList<String>(parts);
604 }
605
606
607
608
609 public boolean getVerbose() {
610 return this.verbose;
611 }
612
613
614
615
616 public void setVerbose(boolean verbose) {
617 this.verbose = verbose;
618 }
619
620
621
622
623 public boolean getDebug() {
624 return this.debug;
625 }
626
627
628
629
630 public void setDebug(boolean debug) {
631 this.debug = debug;
632 }
633
634
635
636
637 public int getTolerance() {
638 return this.tolerance;
639 }
640
641
642
643
644
645
646 public void setTolerance(int tolerance) {
647 this.tolerance = tolerance;
648 }
649
650
651
652
653
654 public String getScriptBaseClass() {
655 return this.scriptBaseClass;
656 }
657
658
659
660
661
662 public void setScriptBaseClass(String scriptBaseClass) {
663 this.scriptBaseClass = scriptBaseClass;
664 }
665
666 public ParserPluginFactory getPluginFactory() {
667 if (pluginFactory == null) {
668 pluginFactory = ParserPluginFactory.newInstance(true);
669 }
670 return pluginFactory;
671 }
672
673 public void setPluginFactory(ParserPluginFactory pluginFactory) {
674 this.pluginFactory = pluginFactory;
675 }
676
677 public void setScriptExtensions(Set<String> scriptExtensions) {
678 if(scriptExtensions == null) scriptExtensions = new LinkedHashSet<String>();
679 this.scriptExtensions = scriptExtensions;
680 }
681
682 public Set<String> getScriptExtensions() {
683 if(scriptExtensions == null || scriptExtensions.isEmpty()) {
684
685
686
687
688
689
690 scriptExtensions = SourceExtensionHandler.getRegisteredExtensions(
691 this.getClass().getClassLoader());
692 }
693 return scriptExtensions;
694 }
695
696 public String getDefaultScriptExtension() {
697 return defaultScriptExtension;
698 }
699
700
701 public void setDefaultScriptExtension(String defaultScriptExtension) {
702 this.defaultScriptExtension = defaultScriptExtension;
703 }
704
705 public void setRecompileGroovySource(boolean recompile) {
706 recompileGroovySource = recompile;
707 }
708
709 public boolean getRecompileGroovySource(){
710 return recompileGroovySource;
711 }
712
713 public void setMinimumRecompilationInterval(int time) {
714 minimumRecompilationInterval = Math.max(0,time);
715 }
716
717 public int getMinimumRecompilationInterval() {
718 return minimumRecompilationInterval;
719 }
720
721
722
723
724
725
726
727
728 public void setTargetBytecode(String version) {
729 for (String allowedJdk : ALLOWED_JDKS) {
730 if (allowedJdk.equals(version)) {
731 this.targetBytecode = version;
732 }
733 }
734 }
735
736
737
738
739
740
741 public String getTargetBytecode() {
742 return this.targetBytecode;
743 }
744
745 private static String getVMVersion() {
746 try {
747 Class.forName(JDK5_CLASSNAME_CHECK);
748 return POST_JDK5;
749 } catch(Exception ex) {
750
751 }
752 return PRE_JDK5;
753 }
754
755
756
757
758
759 public Map<String, Object> getJointCompilationOptions() {
760 return jointCompilationOptions;
761 }
762
763
764
765
766
767
768 public void setJointCompilationOptions(Map<String, Object> options) {
769 jointCompilationOptions = options;
770 }
771
772
773
774
775
776 public Map<String, Boolean> getOptimizationOptions() {
777 return optimizationOptions;
778 }
779
780
781
782
783
784
785
786
787
788 public void setOptimizationOptions(Map<String, Boolean> options) {
789 if (options==null) throw new IllegalArgumentException("provided option map must not be null");
790 optimizationOptions = options;
791 }
792
793
794
795
796
797
798
799 public CompilerConfiguration addCompilationCustomizers(CompilationCustomizer... customizers) {
800 if (customizers==null) throw new IllegalArgumentException("provided customizers list must not be null");
801 compilationCustomizers.addAll(Arrays.asList(customizers));
802 return this;
803 }
804
805
806
807
808
809 public List<CompilationCustomizer> getCompilationCustomizers() {
810 return compilationCustomizers;
811 }
812
813
814
815
816
817 public Set<String> getDisabledGlobalASTTransformations() {
818 return disabledGlobalASTTransformations;
819 }
820
821
822
823
824
825
826
827
828
829
830
831
832 public void setDisabledGlobalASTTransformations(final Set<String> disabledGlobalASTTransformations) {
833 this.disabledGlobalASTTransformations = disabledGlobalASTTransformations;
834 }
835
836 public BytecodeProcessor getBytecodePostprocessor() {
837 return bytecodePostprocessor;
838 }
839
840 public void setBytecodePostprocessor(final BytecodeProcessor bytecodePostprocessor) {
841 this.bytecodePostprocessor = bytecodePostprocessor;
842 }
843 }